<?php

// 将url归一化处理 获取绝对url，host，domain等信息
function splitURL($url) {
	if (! preg_match ( "#^[a-z0-9-]+://# i", $url ))
		$url = "http://" . $url;
	
	$parts = @parse_url ( $url );
	
	if (! isset ( $parts ))
		return null;
	
	$protocol = $parts ["scheme"] . "://";
	$host = (isset ( $parts ["host"] ) ? $parts ["host"] : "");
	$path = (isset ( $parts ["path"] ) ? $parts ["path"] : "");
	$query = (isset ( $parts ["query"] ) ? "?" . $parts ["query"] : "");
	$auth_username = (isset ( $parts ["user"] ) ? $parts ["user"] : "");
	$auth_password = (isset ( $parts ["pass"] ) ? $parts ["pass"] : "");
	$port = (isset ( $parts ["port"] ) ? (":" . $parts ["port"]) : "");
	
	// Host is case-insensitive
	$host = strtolower ( $host );
	
	// File
	preg_match ( "#^(.*/)([^/]*)$#", $path, $match ); // Alles ab dem letzten "/"
	if (isset ( $match [0] )) {
		$file = trim ( $match [2] );
		$path = trim ( $match [1] );
	} else {
		$file = "";
	}
	
	$domain = domain ( $host );
	
	// DEFAULT VALUES für protocol, path, port etc. (wenn noch nicht gesetzt)
	
	// Wenn Protokoll leer -> Protokoll ist "http://"
	if ($protocol == "")
		$protocol = "http://";
		
		// Wenn Port leer -> Port setzen auf 80 or 443
		// (abhängig vom Protokoll)
		// if ($port == "")
		// {
		// if (strtolower($protocol) == "http://") $port=80;
		// if (strtolower($protocol) == "https://") $port=443;
		// }
		
	// Wenn Pfad leet -> Pfad ist "/"
	if ($path == "")
		$path = "/";
	
	$url_parts ["protocol"] = $protocol;
	$url_parts ["host"] = $host;
	$url_parts ["path"] = $path;
	$url_parts ["file"] = $file;
	$url_parts ["query"] = $query;
	$url_parts ["domain"] = $domain;
	$url_parts ["port"] = $port;
	
	$url_parts ["auth_username"] = $auth_username;
	$url_parts ["auth_password"] = $auth_password;
	
	return $url_parts;
}
function change_url_from_relative_to_absolute($url_parts, $link) {
	$link = trim ( $link );
	// Remove anchor ("#..."), but ONLY at the end, not if # is at the beginning !
	$link = preg_replace ( "/^(.{1,})#.{0,}$/", "\\1", $link );
	
	// if need parser
	$is_need_parser = FALSE;
	
	// Strange link like "//foo.htm" -> make it to "http://foo.html"
	if (substr ( $link, 0, 2 ) == "//") {
		$link = "http:" . $link;
		$is_need_parser = TRUE;
	}	

	// 1. relative link starts with "/" --> doc_root
	// "/index.html" -> "http://www.foo.com/index.html"
	elseif (substr ( $link, 0, 1 ) == "/") {
		$link = $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["port"] . $link;
	}	

	// 2. "./foo.htm" -> "foo.htm"
	elseif (substr ( $link, 0, 2 ) == "./") {
		$link = $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["port"] . $url_parts ["path"] . substr ( $link, 2 );
	}	

	// 3. Link is an absolute Link with a given protocol and host (f.e. "http://..." or "android-app://...)
	// DO NOTHING
	elseif (preg_match ( "#^[a-z0-9-]{1,}(:\/\/)# i", $link )) {
		$link = $link;
		$is_need_parser = TRUE;
	}	

	// 4. Link is stuff like "javascript: ..." or something
	elseif (preg_match ( "/^[a-zA-Z]{0,}:[^\/]{0,1}/", $link )) {
		$link = "";
	}	

	// 5. "../../foo.html" -> remove the last path from our actual path
	// and remove "../" from link at the same time until there are
	// no more "../" at the beginning of the link
	elseif (substr ( $link, 0, 3 ) == "../") {
		$new_path = $url_parts ["path"];
		while ( substr ( $link, 0, 3 ) == "../" ) {
			$new_path = preg_replace ( '/\/[^\/]{0,}\/$/', "/", $new_path );
			$link = substr ( $link, 3 );
		}
		$link = $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["port"] . $new_path . $link;
	}	

	// 6. link starts with #
	// -> leads to the same site as we are on, trash
	elseif (substr ( $link, 0, 1 ) == "#") {
		$link = "";
	}	

	// 7. link starts with "?"
	elseif (substr ( $link, 0, 1 ) == "?") {
		$link = $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["port"] . $url_parts ["path"] . $url_parts ["file"] . $link;
	} 

	elseif (preg_match ( "/javascript:(.*)/", $link )) {
		$link = "";
	} 	

	// 7. thats it, else the abs_path is simply PATH.LINK ...
	else {
		$link = $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["port"] . $url_parts ["path"] . $link;
	}
	
	if ("http:///" === $link || "https:///" === $link || "http://" === $link || "https://" === $link) {
		$link = "";
	}
	
	if ($link == "")
		return null;
	
	$link = str_replace ( array (
			"\n",
			"\r" 
	), "", $link );
	
	$url_info ['link'] = $link;
	
	if ($is_need_parser) {
		$new_urlparts = splitURL ( $link );
		
		if (empty ( $new_urlparts )) {
			return null;
		}
		
		$url_info ['link'] = make_url ( $new_urlparts );
		$host = $new_urlparts ['host'];
		$url_info ['host'] = $host;
		if ($host === $url_parts ['host']) {
			$url_info ['domain'] = $url_parts ['domain'];
		} else {
			$url_info ['domain'] = domain ( $host );
		}
	} else {
		$url_info ['host'] = $url_parts ['host'];
		$url_info ['domain'] = $url_parts ['domain'];
	}
	
	$url_info ['link'] = decodeHtmlEntities ( $url_info ['link'] );
	
	if (check_is_html ( $url_info ["link"] )) {
		return $url_info;
	} else {
		return FALSE;
	}
}
function make_url($url_parts) {
	return $url_parts ["protocol"] . $url_parts ["host"] . $url_parts ["path"] . $url_parts ["file"] . $url_parts ["query"];
}
function normalization($url) {
	$url_parts = splitURL ( $url );
	$url_info ['url'] = make_url ( $url_parts );
	$url_info ['domain'] = $url_parts ['domain'];
	$url_info ['host'] = $url_parts ['host'];
	return $url_info;
}
function decodeHtmlEntities($string) {
	// Entities-replacements
	$entities = array (
			"'&(quot|#34);'i",
			"'&(amp|#38);'i",
			"'&(lt|#60);'i",
			"'&(gt|#62);'i",
			"'&(nbsp|#160);'i",
			"'&(iexcl|#161);'i",
			"'&(cent|#162);'i",
			"'&(pound|#163);'i",
			"'&(copy|#169);'i" 
	);
	
	$entitie_replacements = array (
			"\"",
			"&",
			"<",
			">",
			" ",
			chr ( 161 ),
			chr ( 162 ),
			chr ( 163 ),
			chr ( 169 ) 
	);
	
	$string = preg_replace ( $entities, $entitie_replacements, $string );
	
	// Numeric haracter reference replacement (non-HEX), like &#64; => "@"
	$string = preg_replace_callback ( "/&#([0-9]{1,4});/ i", function ($m) {
		return chr ( $m [1] );
	}, $string );
	
	// Numeric character reference replacement (HEX), like &#x2f; => "/"
	$string = preg_replace_callback ( "/&#x([0-9a-z]{2,4});/ i", function ($m) {
		return chr ( hexdec ( $m [1] ) );
	}, $string );
	
	return $string;
}
function check_is_index($url) {
	$is_index = FALSE;
	
	if (substr ( $url, - 1 ) === "/") {
		$judge_length = strlen ( $url ) - strlen ( str_replace ( "/", "", $url ) );
		if ($judge_length <= 5) {
			$is_index = TRUE;
		}
	}
	
	if (stripos ( $url, "index" ) != FALSE) {
		$is_index = TRUE;
	}
	
	if (stripos ( $url, "list" ) != FALSE) {
		$is_index = TRUE;
	}
	
	return $is_index;
}
function check_is_html($url) {
	$url_parts = splitURL ( $url );
	if (! empty ( $url_parts ['file'] )) {
		$i = strpos ( $url_parts ['file'], "." );
		if ($i === FALSE) {
			return TRUE;
		} else {
			$extension = strtoupper ( substr ( $url_parts ['file'], $i + 1 ) );
			$image_extension = array (
					"JPG",
					"JPEG",
					"PNG",
					"GIF",
					"PDF",
					"TXT",
					"BMP",
					"DOC",
					"PPT",
					"ZIP",
					"TAR",
					"GZ",
					"EXE",
					"RAR",
					"DOCX",
					"PPTX",
					"XLS",
					"XLSX"
			);
			
			if (in_array ( $extension, $image_extension )) {
				return FALSE;
			} else {
				return TRUE;
			}
		}
	} else {
		return TRUE;
	}
}
